import logging
import traceback
from urllib.parse import urlparse
from flask import jsonify, request, current_app, g
from sqlalchemy import func
from app.models.user import User, ShareRelation
from app.core.extensions import db
from app.models.system import Banner, Notice, Article, Feedback
from app.utils.cos_utils import get_cos_client
from app.utils.leaf import Snowflake
import datetime
from werkzeug.utils import secure_filename

def get_banners():
    """获取轮播图列表"""
    try:
        banners = Banner.query.filter_by(status=1).order_by(Banner.sort.asc()).all()

        return {
            "code": 1,
            "msg": "获取成功",
            "data": {
                "list": [banner.to_dict() for banner in banners]
            }
        }

    except Exception as e:
        return {"code": 0, "msg": f"服务器错误: {str(e)}"}


def get_notices():
    """获取公告列表"""
    try:
        notices = Notice.query.filter_by(status=1).order_by(Notice.sort.asc()).all()

        return {
            "code": 1,
            "msg": "获取成功",
            "data": {
                "list": [notice.to_dict() for notice in notices]
            }
        }

    except Exception as e:
        return {"code": 0, "msg": f"服务器错误: {str(e)}"}


def get_articles():
    """获取文章列表"""
    try:
        articles = Article.query.filter_by(status=1).order_by(
            Article.is_top.desc(),
            Article.sort_number.asc(),
            Article.update_time.desc()
        ).all()

        return {
            "code": 1,
            "msg": "获取成功",
            "data": {
                "list": [article.to_dict() for article in articles]
            }
        }

    except Exception as e:
        return {"code": 0, "msg": f"服务器错误: {str(e)}"}


def bind_share_relation(sharer_id, user_id):
    """绑定分享关系"""
    if not sharer_id or not user_id:
        return {'code': 400, 'msg': '参数缺失'}

    if sharer_id == user_id:
        return {'code': 200, 'msg': '不能绑定自己'}

    # 检查是否已绑定
    existing = ShareRelation.query.filter_by(invitee_id=user_id).first()
    if existing:
        return {'code': 200, 'msg': '已绑定过推荐人'}

    try:
        # 绑定关系
        relation = ShareRelation(sharer_id=sharer_id, invitee_id=user_id)
        db.session.add(relation)

        # 推荐人使用次数 +2
        sharer = User.query.filter_by(user_id=sharer_id).first()
        if sharer:
            sharer.usage_count = sharer.usage_count + 2

        db.session.commit()
        return {'code': 1, 'msg': '绑定成功'}

    except Exception as e:
        db.session.rollback()
        return {'code': 500, 'msg': '服务器错误', 'error': str(e)}


def get_share_count(sharer_id):
    """获取分享数量"""
    if not sharer_id:
        return {'code': 400, 'msg': '参数缺失'}

    try:
        count = ShareRelation.query.filter_by(sharer_id=sharer_id).count()
        return {'code': 1, 'msg': '查询成功', 'data': {'count': count}}
    except Exception as e:
        return {'code': 500, 'msg': '服务器异常', 'error': str(e)}


def get_user_top_list():
    """获取用户排行榜"""
    try:
        # 第一步：统计 sharer_id 出现次数（就是邀请人数）
        sharer_counts = (
            db.session.query(
                ShareRelation.sharer_id,
                func.count(ShareRelation.invitee_id).label('invite_count')
            )
            .group_by(ShareRelation.sharer_id)
            .order_by(func.count(ShareRelation.invitee_id).desc())
            .limit(10)
            .all()
        )

        if not sharer_counts:
            return {
                "code": 1,
                "msg": "暂无数据",
                "data": {
                    "list": []
                }
            }

        # 第二步：提取出 sharer_id 列表
        sharer_ids = [item.sharer_id for item in sharer_counts]

        # 第三步：根据 sharer_id 查询用户信息
        users = User.query.filter(User.user_id.in_(sharer_ids)).all()
        user_dict = {user.user_id: user for user in users}  # 方便通过 id 找用户信息

        # 第四步：组装返回数据
        result = []
        for idx, item in enumerate(sharer_counts, start=1):
            user = user_dict.get(item.sharer_id)
            if user:
                result.append({
                    "rank": idx,  # 排名
                    "id": user.user_id,
                    "nickname": user.nick_name if hasattr(user, 'nick_name') else '',
                    "avatar_url": user.avatar_url if hasattr(user, 'avatar_url') else '',
                    "amount": item.invite_count  # 邀请人数
                })

        return {
            "code": 1,
            "msg": "获取成功",
            "data": {
                "list": result
            }
        }

    except Exception as e:
        return {
            "code": 0,
            "msg": "服务器异常",
            "data": {}
        }


def create_feedback(data):
    """创建用户反馈"""
    try:
        # 必填字段验证
        if not data:
            return {"code": 400, "message": "未提供数据"}, 400

        required_fields = ['content']
        missing_fields = [field for field in required_fields if field not in data or not data[field]]
        if missing_fields:
            return {"code": 400, "message": f"缺少必填字段: {', '.join(missing_fields)}"}, 400

        # 创建反馈对象并保存到数据库
        feedback = Feedback(
            content=data.get('content', ''),
            contact=data.get('contact', ''),
            status=0,
            user_id=data.get('user_id', ''),
            create_time=datetime.datetime.now()
        )
        db.session.add(feedback)
        db.session.commit()
        return {
            "code": 200,
            "message": "反馈提交成功",
        }
    except Exception as e:
        # 回滚事务
        db.session.rollback()
        return {"code": 500, "message": "服务器内部错误", "error": str(e)}, 500


def upload_file_to_cos():
    if 'file' not in request.files:
        return jsonify({'code': 400, 'msg': '未检测到上传文件'}), 400

    file = request.files['file']
    if file.filename == '':
        return jsonify({'code': 400, 'msg': '文件名为空'}), 400

    try:

        # 初始化 COS 客户端
        cos_client, bucket, region = get_cos_client(tenant_id=14)

        # 构造唯一文件名
        snowflake = Snowflake(worker_id=1)
        unique_id = str(snowflake.get_id())  # 确保是字符串
        safe_filename = secure_filename(file.filename)  # 安全处理文件名
        filename = f'image/{unique_id}_{safe_filename}'

        # 读取文件内容
        file_content = file.read()

        # 上传到 COS
        cos_client.put_object(
            Bucket=bucket,
            Body=file_content,
            Key=filename,
            EnableMD5=False
        )

        # 构造文件访问 URL
        file_url = f"https://{bucket}.cos.{region}.myqcloud.com/{filename}"
        return jsonify({'code': 1, 'msg': '上传成功', 'url': file_url})

    except Exception as e:
        logging.error(f"上传失败: {e}")
        logging.error(traceback.format_exc())
        return jsonify({'code': 500, 'msg': '上传失败', 'error': str(e)}), 500

def upload_local_file_to_cos(local_file_path, filename=None):
    try:
        # 如果没指定上传后的文件名，就用本地文件名
        if not filename:
            import os
            filename = 'service-kf.jpg'  # 默认文件名，可以根据需要修改
        from app.utils.cos_utils import get_cos_client
        cos_client, bucket, region = get_cos_client(tenant_id=g.tenant_id)
        # 读取本地文件
        with open(local_file_path, 'rb') as f:
            file_content = f.read()

        # 上传文件
        cos_client.put_object(
            Bucket=bucket,
            Body=file_content,
            Key=filename,
            EnableMD5=False
        )

        file_url = f"https://{bucket}.cos.{region}.myqcloud.com/{filename}"
        return {
            'code': 1,
            'msg': '上传成功',
            'url': file_url
        }

    except Exception as e:
        logging.error(e)
        return {
            'code': 500,
            'msg': '上传失败',
            'error': str(e)
        }


def extract_cos_key(file_url):
    """
    从腾讯云 COS URL 中提取文件 key
    """
    parsed_url = urlparse(file_url)
    return parsed_url.path.lstrip('/').strip()  # 去掉开头的 /


def delete_file_from_cos(filename):
    """
    删除 COS 上指定的文件
    :param filename: 文件在 COS 上的 Key（如 xxx.png）
    :return: 删除结果 dict
    """
    import logging
    try:
        from app.utils.cos_utils import get_cos_client
        cos_client, bucket, region = get_cos_client(tenant_id=g.tenant_id)
        cos_client.delete_object(
            Bucket=bucket,
            Key=extract_cos_key(filename)  # 提取文件 key
        )
        return True
    except Exception as e:
        logging.error(f"删除文件失败: {e}")
        return False
